package com.boxman;

import com.common.GameBoard;
import com.common.InputBox;

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JToolBar;

// 主窗口
class MainWindow extends JFrame implements ActionListener, Game.Callback, KeyListener {
    private final Game mGame;                       // 游戏
    private final JMenuItem mMenuItemRestart;       // "重玩本关"菜单项
    private final JMenuItem mMenuItemSelectLevel;   // "选关"菜单项
    private final JMenuItem mMenuItemUndo;          // "回退"菜单项
    private final JLabel mLabelLevel;               // "关卡数"标签
    private final JLabel mLabelMoveCount;           // "移动次数"标签

    /**
     * 构造方法。
     */
    public MainWindow() {
        // 设置当单击右上角的X按钮时退出程序
        super.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        // 设置窗口标题
        super.setTitle(Const.getString("IDS_APP_NAME"));
        
        // 设置窗口尺寸不能改变
        super.setResizable(false);
        
        // 设置窗口尺寸
        super.setSize(Const.WIDTH, Const.HEIGHT);
        
        // 设置窗口居中
        super.setLocationRelativeTo(null);

        // 监听键盘事件
        super.addKeyListener(this);
        
        // 创建菜单栏
        final JMenuBar mainMenuBar = new JMenuBar();
        super.add(mainMenuBar, BorderLayout.NORTH);

        // 创建"游戏"菜单
        final JMenu menuGame = new JMenu(Const.getString("IDS_GAME"));
        mainMenuBar.add(menuGame);

        // 创建"重玩本关"菜单项
        mMenuItemRestart = new JMenuItem(Const.getString("IDS_RESTART"));
        mMenuItemRestart.addActionListener(this);
        menuGame.add(mMenuItemRestart);

        // 创建"选关"菜单项
        mMenuItemSelectLevel = new JMenuItem(Const.getString("IDS_SELECT_LEVEL"));
        mMenuItemSelectLevel.addActionListener(this);
        menuGame.add(mMenuItemSelectLevel);
        
        // 创建"回退"菜单项
        mMenuItemUndo = new JMenuItem(Const.getString("IDS_UNDO"));
        mMenuItemUndo.addActionListener(this);
        menuGame.add(mMenuItemUndo);
        
        // 创建状态栏
        final JToolBar statusBar = new JToolBar();
        statusBar.setLayout(new GridLayout(1, Const.STATUS_BAR_PART_COUNT));
        statusBar.setFloatable(false);
        super.add(statusBar, BorderLayout.SOUTH);
        
        // 设置"关卡数"标签
        mLabelLevel = new JLabel(String.format(Const.getString("IDS_LEVEL"), 1));
        mLabelLevel.setBorder(BorderFactory.createEtchedBorder());
        statusBar.add(mLabelLevel, BorderLayout.CENTER);

        // 设置"移动次数"标签
        mLabelMoveCount = new JLabel(String.format(Const.getString("IDS_MOVE_COUNT"), 0));
        mLabelMoveCount.setBorder(BorderFactory.createEtchedBorder());
        statusBar.add(mLabelMoveCount, BorderLayout.EAST);
        
        // 创建游戏区域
        final GameBoard gameBoard = new GameBoard(this, 0, 0, Const.GAME_BOARD_WIDTH, Const.GAME_BOARD_HEIGHT);

        // 创建游戏
        mGame = new Game(this, gameBoard.getDrawer(), gameBoard);
    }

    /**
     * 菜单的单击响应方法。
     * @param e 事件相关信息
     */
    @Override
    public void actionPerformed(ActionEvent e) {
        final Object source = e.getSource();
        if (source == mMenuItemRestart) {
            this.onMenuItemRestartClicked();
        } else if (source == mMenuItemSelectLevel) {
            this.onMenuItemSelectLevelClicked();
        } else if (source == mMenuItemUndo) {
            this.onMenuItemUndoClicked();
        }
    }

    /**
     * 按键事件的响应方法。
     * @param e 事件相关信息
     */
    @Override
    public void keyPressed(KeyEvent e) {
        mGame.onKeyPressed(e.getKeyCode());
    }

    @Override
    public void keyReleased(KeyEvent e) {
    }
    
    @Override
    public void keyTyped(KeyEvent e) {
    }

    /**
     * 游戏结束事件的响应方法。
     * @param allOver   全部通关则为 true，否则为 false
     */
    @Override
    public void onGameOver(boolean allOver) {
        if (allOver) {
            JOptionPane.showMessageDialog(this, Const.getString("IDS_WON_ALL_OVER"), " ", JOptionPane.INFORMATION_MESSAGE); 
        } else {
            JOptionPane.showMessageDialog(this, Const.getString("IDS_WON"), " ", JOptionPane.INFORMATION_MESSAGE);
        }
    }

    /**
     * 进入关卡事件的响应方法。
     * @param level    关卡数
     */
    @Override
    public void onGotoLevel(int level) {
        String text = String.format(Const.getString("IDS_LEVEL"), level);
        mLabelLevel.setText(text);
        text = String.format(Const.getString("IDS_MOVE_COUNT"), 0);
        mLabelMoveCount.setText(text);
    }

    /**
     * 小人移动事件的响应方法。
     * @param moveCount    小人移动次数
     */
    @Override
    public void onManMoved(int moveCount) {
        final String text = String.format(Const.getString("IDS_MOVE_COUNT"), moveCount);
        mLabelMoveCount.setText(text);
    }
    
    /**
     * "重玩本关"菜单项的单击响应方法。
     */
    private void onMenuItemRestartClicked() {
        mGame.restart();
    }

    /**
     * "选关"菜单项的单击响应方法。
     */
    private void onMenuItemSelectLevelClicked() {
        // 显示输入窗口
        final String tipText = String.format(Const.getString("IDS_PLEASE_INPUT_NUMBER"), 1, Const.LEVEL_COUNT);
        final int level = InputBox.getIntValue(mGame.getLevel(), Const.LEVEL_COUNT, 1, this, tipText);

        // 进入关卡
        if (level != mGame.getLevel()) {
            mGame.gotoLevel(level);
        }
    }

    /**
     * "回退"菜单项的单击响应方法。
     */
    private void onMenuItemUndoClicked() {
        mGame.undo();
    }
}
